<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Refresher</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Chapter 1. Boost.Beast">
<link rel="up" href="../using_io.html" title="Networking">
<link rel="prev" href="../using_io.html" title="Networking">
<link rel="next" href="stream_types.html" title="Streams">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../using_io.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_io.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stream_types.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="beast.using_io.asio_refresher"></a><a class="link" href="asio_refresher.html" title="Refresher">Refresher</a>
</h3></div></div></div>
<p>
        To use Beast effectively, a prior understanding of Networking is required.
        This section reviews these concepts as a reminder and guide for further learning.
      </p>
<p>
        A <a href="https://en.wikipedia.org/wiki/Computer_network" target="_top"><span class="emphasis"><em>network</em></span></a>
        allows programs located anywhere to exchange information after opting-in
        to communications by establishing a <a href="https://en.wikipedia.org/wiki/Data_link" target="_top"><span class="emphasis"><em>connection</em></span></a>.
        Data may be reliably transferred across a connection in both directions (<a href="https://en.wikipedia.org/wiki/Duplex_(telecommunications)" target="_top"><span class="emphasis"><em>full-duplex</em></span></a>)
        with bytes arriving in the same order they were sent. These connections,
        along with the objects and types used to represent them, are collectively
        termed <a class="link" href="../concepts/streams.html" title="Streams"><span class="emphasis"><em>streams</em></span></a>.
        The computer or device attached to the network is called a <a href="https://en.wikipedia.org/wiki/Host_(network)" target="_top"><span class="emphasis"><em>host</em></span></a>,
        and the program on the other end of an established connection is called a
        <a href="https://en.wikipedia.org/wiki/Peer-to-peer" target="_top"><span class="emphasis"><em>peer</em></span></a>.
      </p>
<p>
        The <a href="https://en.wikipedia.org/wiki/Internet" target="_top"><span class="emphasis"><em>internet</em></span></a>
        is a global network of interconnected computers that use a variety of standardized
        communication protocols to exchange information. The most popular protocol
        is <a href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol" target="_top"><span class="emphasis"><em>TCP/IP</em></span></a>,
        which this library relies on exclusively. The protocol takes care of the
        low level details so that applications see a <span class="emphasis"><em>stream</em></span>,
        which is the reliable, full-duplex connection carrying the ordered set of
        bytes described above. A <a href="https://en.wikipedia.org/wiki/Server_(computing)" target="_top"><span class="emphasis"><em>server</em></span></a>
        is a powerful, always-on host at a well-known network name or network address
        which provides data services. A <a href="https://en.wikipedia.org/wiki/Client_(computing)" target="_top"><span class="emphasis"><em>client</em></span></a>
        is a transient peer which connects to a server to exchange data, and goes
        offline.
      </p>
<p>
        A vendor supplies a program called a <a href="https://en.wikipedia.org/wiki/Device_driver" target="_top"><span class="emphasis"><em>device
        driver</em></span></a>, enabling networking hardware such as an <a href="https://en.wikipedia.org/wiki/Network_interface_controller" target="_top"><span class="emphasis"><em>ethernet
        adaptor</em></span></a> to talk to the operating system. This in turn
        permits running programs to interact with networking using various flavors
        of interfaces such as <a href="https://en.wikipedia.org/wiki/Berkeley_sockets" target="_top"><span class="emphasis"><em>Berkeley
        sockets</em></span></a> or <a href="https://en.wikipedia.org/wiki/Winsock" target="_top"><span class="emphasis"><em>Windows
        Sockets 2</em></span></a> ("Winsock").
      </p>
<p>
        Networking in C++, represented by <a href="../../../../../../libs/asio/index.html" target="_top">Boost.Asio</a>,
        <a href="https://think-async.com/Asio/" target="_top">Asio</a>, and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4771.pdf" target="_top">Networking
        TS</a>, provides a layer of abstraction to interact portably with the
        operating system facilities for not just networking but general <a href="https://en.wikipedia.org/wiki/Input/output" target="_top"><span class="emphasis"><em>input/output</em></span></a>
        ("I/O").
      </p>
<h5>
<a name="beast.using_io.asio_refresher.h0"></a>
        <span class="phrase"><a name="beast.using_io.asio_refresher.buffers"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.buffers">Buffers</a>
      </h5>
<p>
        A <a href="https://en.wikipedia.org/wiki/Data_buffer" target="_top"><span class="emphasis"><em>buffer</em></span></a>
        holds a contiguous sequence of bytes used when performing I/O. The types
        <a href="../../../../../../doc/html/boost_asio/reference/const_buffer.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span></code></a>
        and <a href="../../../../../../doc/html/boost_asio/reference/mutable_buffer.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">mutable_buffer</span></code></a>
        represent these memory regions as type-safe pointer/size pairs:
      </p>
<pre class="programlisting"><span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span> <span class="identifier">cb</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">string_view</span><span class="special">(</span><span class="keyword">reinterpret_cast</span><span class="special">&lt;</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*&gt;(</span>
    <span class="identifier">cb</span><span class="special">.</span><span class="identifier">data</span><span class="special">()),</span> <span class="identifier">cb</span><span class="special">.</span><span class="identifier">size</span><span class="special">())</span> <span class="special">==</span> <span class="string">"Hello, world!"</span><span class="special">);</span>

<span class="keyword">char</span> <span class="identifier">storage</span><span class="special">[</span><span class="number">13</span><span class="special">];</span>
<span class="identifier">net</span><span class="special">::</span><span class="identifier">mutable_buffer</span> <span class="identifier">mb</span><span class="special">(</span><span class="identifier">storage</span><span class="special">,</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">storage</span><span class="special">));</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">memcpy</span><span class="special">(</span><span class="identifier">mb</span><span class="special">.</span><span class="identifier">data</span><span class="special">(),</span> <span class="identifier">cb</span><span class="special">.</span><span class="identifier">data</span><span class="special">(),</span> <span class="identifier">mb</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">string_view</span><span class="special">(</span><span class="keyword">reinterpret_cast</span><span class="special">&lt;</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*&gt;(</span>
    <span class="identifier">mb</span><span class="special">.</span><span class="identifier">data</span><span class="special">()),</span> <span class="identifier">mb</span><span class="special">.</span><span class="identifier">size</span><span class="special">())</span> <span class="special">==</span> <span class="string">"Hello, world!"</span><span class="special">);</span>
</pre>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
          <code class="computeroutput"><span class="identifier">const_buffer</span></code> and <code class="computeroutput"><span class="identifier">mutable_buffer</span></code> are preferred over <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">span</span><span class="special">&lt;</span><span class="identifier">byte</span><span class="special">&gt;</span></code>
          and <code class="computeroutput"><span class="identifier">span</span><span class="special">&lt;</span><span class="identifier">byte</span> <span class="keyword">const</span><span class="special">&gt;</span></code> because <a href="https://en.cppreference.com/w/cpp/container/span" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">span</span></code></a> does too much. It not only
          type-erases the original pointer but also recasts it to a pointer-to-byte.
          The operating system doesn't care about this, but if a user wants to send
          and receive an array of some other type, presenting it as an array of bytes
          which supports bitwise operations is unnecessary. Custom buffer types also
          enable implementations to provide targeted features such as <a href="../../../../../../doc/html/boost_asio/overview/core/buffers.html#boost_asio.overview.core.buffers.buffer_debugging" target="_top"><span class="emphasis"><em>buffer
          debugging</em></span></a> without changing the more general vocabulary
          types.
        </p></td></tr>
</table></div>
<p>
        The concepts <a href="../../../../../../doc/html/boost_asio/reference/ConstBufferSequence.html" target="_top"><span class="emphasis"><em>ConstBufferSequence</em></span></a>
        and <a href="../../../../../../doc/html/boost_asio/reference/MutableBufferSequence.html" target="_top"><span class="emphasis"><em>MutableBufferSequence</em></span></a>
        describe bidirectional ranges whose value type is convertible to <code class="computeroutput"><span class="identifier">const_buffer</span></code> and <code class="computeroutput"><span class="identifier">mutable_buffer</span></code>
        respectively. These sequences allow transacting with multiple buffers in
        a single function call, a technique called <a href="https://en.wikipedia.org/wiki/Vectored_I/O" target="_top"><span class="emphasis"><em>scatter/gather
        I/O</em></span></a>. Buffers and buffer sequences are non-owning; copies
        produce shallow references and not duplicates of the underlying memory. Each
        of these statements declares a buffer sequence:
      </p>
<pre class="programlisting"><span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span> <span class="identifier">b1</span><span class="special">;</span>                   <span class="comment">// a ConstBufferSequence by definition</span>
<span class="identifier">net</span><span class="special">::</span><span class="identifier">mutable_buffer</span> <span class="identifier">b2</span><span class="special">;</span>                 <span class="comment">// a MutableBufferSequence by definition</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;</span> <span class="identifier">b3</span><span class="special">;</span>    <span class="comment">// A ConstBufferSequence by named requirements</span>
</pre>
<p>
        The functions <a href="../../../../../../doc/html/boost_asio/reference/buffer_size.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_size</span></code></a>
        and <a href="../../../../../../doc/html/boost_asio/reference/buffer_copy.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_copy</span></code></a>
        determine the total number of bytes in a buffer sequence, and transfer some
        or all of bytes from one buffer sequence to another respectively. The function
        <code class="computeroutput"><span class="identifier">buffer_size</span></code> is a customization
        point: user defined overloads in foreign namespaces are possible, and callers
        should invoke <code class="computeroutput"><span class="identifier">buffer_size</span></code>
        without namespace qualification. The functions <a href="../../../../../../doc/html/boost_asio/reference/buffer_sequence_begin.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_sequence_begin</span></code></a>
        and <a href="../../../../../../doc/html/boost_asio/reference/buffer_sequence_end.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_sequence_end</span></code></a>
        are used to obtain a pair of iterators for traversing the sequence. Beast
        provides a set of buffer sequence types and algorithms such as <a class="link" href="../ref/boost__beast__buffers_cat.html" title="buffers_cat"><code class="computeroutput"><span class="identifier">buffers_cat</span></code></a>, <a class="link" href="../ref/boost__beast__buffers_front.html" title="buffers_front"><code class="computeroutput"><span class="identifier">buffers_front</span></code></a>, <a class="link" href="../ref/boost__beast__buffers_prefix.html" title="buffers_prefix"><code class="computeroutput"><span class="identifier">buffers_prefix</span></code></a>, <a class="link" href="../ref/boost__beast__buffers_range.html" title="buffers_range"><code class="computeroutput"><span class="identifier">buffers_range</span></code></a>, and <a class="link" href="../ref/boost__beast__buffers_suffix.html" title="buffers_suffix"><code class="computeroutput"><span class="identifier">buffers_suffix</span></code></a>. This example returns
        the bytes in a buffer sequence as a string:
      </p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ConstBufferSequence</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">string_from_buffers</span> <span class="special">(</span><span class="identifier">ConstBufferSequence</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">buffers</span><span class="special">)</span>
<span class="special">{</span>
    <span class="comment">// check that the type meets the requirements using the provided type traits</span>
    <span class="keyword">static_assert</span><span class="special">(</span>
        <span class="identifier">net</span><span class="special">::</span><span class="identifier">is_const_buffer_sequence</span><span class="special">&lt;</span><span class="identifier">ConstBufferSequence</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">,</span>
        <span class="string">"ConstBufferSequence type requirements not met"</span><span class="special">);</span>

    <span class="comment">// optimization: reserve all the space for the string first</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span><span class="special">;</span>
    <span class="identifier">result</span><span class="special">.</span><span class="identifier">reserve</span><span class="special">(</span><span class="identifier">beast</span><span class="special">::</span><span class="identifier">buffer_bytes</span><span class="special">(</span><span class="identifier">buffers</span><span class="special">));</span>        <span class="comment">// beast version of net::buffer_size</span>

    <span class="comment">// iterate over each buffer in the sequence and append it to the string</span>
    <span class="keyword">for</span><span class="special">(</span><span class="keyword">auto</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_sequence_begin</span><span class="special">(</span><span class="identifier">buffers</span><span class="special">);</span>  <span class="comment">// returns an iterator to beginning of the sequence</span>
        <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_sequence_end</span><span class="special">(</span><span class="identifier">buffers</span><span class="special">);)</span>       <span class="comment">// returns a past-the-end iterator to the sequence</span>
    <span class="special">{</span>
        <span class="comment">// A buffer sequence iterator's value_type is always convertible to net::const_buffer</span>
        <span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span> <span class="identifier">buffer</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">++;</span>

        <span class="comment">// A cast is always required to out-out of type-safety</span>
        <span class="identifier">result</span><span class="special">.</span><span class="identifier">append</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*&gt;(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">data</span><span class="special">()),</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>
    <span class="special">}</span>
    <span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        The <a class="link" href="../concepts/DynamicBuffer.html" title="DynamicBuffer"><span class="emphasis"><em>DynamicBuffer</em></span></a>
        concept defines a resizable buffer sequence interface. Algorithms may be
        expressed in terms of dynamic buffers when the memory requirements are not
        known ahead of time, for example when reading an HTTP message from a stream.
        Beast provides a well-rounded collection of dynamic buffer types such as
        <a class="link" href="../ref/boost__beast__buffers_adaptor.html" title="buffers_adaptor"><code class="computeroutput"><span class="identifier">buffers_adaptor</span></code></a>,
        <a class="link" href="../ref/boost__beast__flat_buffer.html" title="flat_buffer"><code class="computeroutput"><span class="identifier">flat_buffer</span></code></a>,
        <a class="link" href="../ref/boost__beast__multi_buffer.html" title="multi_buffer"><code class="computeroutput"><span class="identifier">multi_buffer</span></code></a>,
        and <a class="link" href="../ref/boost__beast__static_buffer.html" title="static_buffer"><code class="computeroutput"><span class="identifier">static_buffer</span></code></a>.
        The following function reads data from a <a class="link" href="../ref/boost__beast__tcp_stream.html" title="tcp_stream"><code class="computeroutput"><span class="identifier">tcp_stream</span></code></a> into a dynamic buffer
        until it encountering a newline character, using <a href="../../../../../../doc/html/boost_asio/reference/buffers_iterator.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">buffers_iterator</span></code></a>
        to treat the contents of the buffer as a range of characters:
      </p>
<pre class="programlisting"><span class="comment">// Read a line ending in '\n' from a socket, returning</span>
<span class="comment">// the number of characters up to but not including the newline</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">DynamicBuffer</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">read_line</span><span class="special">(</span><span class="identifier">net</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&amp;</span> <span class="identifier">sock</span><span class="special">,</span> <span class="identifier">DynamicBuffer</span><span class="special">&amp;</span> <span class="identifier">buffer</span><span class="special">)</span>
<span class="special">{</span>
    <span class="comment">// this alias keeps things readable</span>
    <span class="keyword">using</span> <span class="identifier">range</span> <span class="special">=</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">buffers_iterator</span><span class="special">&lt;</span>
        <span class="keyword">typename</span> <span class="identifier">DynamicBuffer</span><span class="special">::</span><span class="identifier">const_buffers_type</span><span class="special">&gt;;</span>

    <span class="keyword">for</span><span class="special">(;;)</span>
    <span class="special">{</span>
        <span class="comment">// get iterators representing the range of characters in the buffer</span>
        <span class="keyword">auto</span> <span class="identifier">begin</span> <span class="special">=</span> <span class="identifier">range</span><span class="special">::</span><span class="identifier">begin</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">data</span><span class="special">());</span>
        <span class="keyword">auto</span> <span class="identifier">end</span> <span class="special">=</span> <span class="identifier">range</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">data</span><span class="special">());</span>

        <span class="comment">// search for "\n" and return if found</span>
        <span class="keyword">auto</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">,</span> <span class="char">'\n'</span><span class="special">);</span>
        <span class="keyword">if</span><span class="special">(</span><span class="identifier">pos</span> <span class="special">!=</span> <span class="identifier">range</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">data</span><span class="special">()))</span>
            <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">distance</span><span class="special">(</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">);</span>

        <span class="comment">// Determine the number of bytes to read,</span>
        <span class="comment">// using available capacity in the buffer first.</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bytes_to_read</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">min</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;(</span>
              <span class="identifier">std</span><span class="special">::</span><span class="identifier">max</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;(</span><span class="number">512</span><span class="special">,</span>                <span class="comment">// under 512 is too little,</span>
                  <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">capacity</span><span class="special">()</span> <span class="special">-</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">size</span><span class="special">()),</span>
              <span class="identifier">std</span><span class="special">::</span><span class="identifier">min</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;(</span><span class="number">65536</span><span class="special">,</span>              <span class="comment">// and over 65536 is too much.</span>
                  <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">max_size</span><span class="special">()</span> <span class="special">-</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">size</span><span class="special">()));</span>

        <span class="comment">// Read up to bytes_to_read bytes into the dynamic buffer</span>
        <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">commit</span><span class="special">(</span><span class="identifier">sock</span><span class="special">.</span><span class="identifier">read_some</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">prepare</span><span class="special">(</span><span class="identifier">bytes_to_read</span><span class="special">)));</span>
    <span class="special">}</span>
<span class="special">}</span>
</pre>
<h5>
<a name="beast.using_io.asio_refresher.h1"></a>
        <span class="phrase"><a name="beast.using_io.asio_refresher.synchronous_i_o"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.synchronous_i_o">Synchronous
        I/O</a>
      </h5>
<p>
        Synchronous input and output is accomplished through blocking function calls
        that return with the result of the operation. Such operations typically cannot
        be canceled and do not have a method for setting a timeout. The <a href="../../../../../../doc/html/boost_asio/reference/SyncReadStream.html" target="_top"><span class="emphasis"><em>SyncReadStream</em></span></a>
        and <a href="../../../../../../doc/html/boost_asio/reference/SyncWriteStream.html" target="_top"><span class="emphasis"><em>SyncWriteStream</em></span></a>
        concepts define requirements for <span class="emphasis"><em>synchronous streams</em></span>:
        a portable I/O abstraction that transfers data using buffer sequences to
        represent bytes and either <code class="computeroutput"><span class="identifier">error_code</span></code>
        or an exception to report any failures. <a href="../../../../../../doc/html/boost_asio/reference/basic_stream_socket.html" target="_top"><span class="emphasis"><em>net::basic_stream_socket</em></span></a>
        is a synchronous stream commonly used to form TCP/IP connections. User-defined
        types which meet the requirements are possible:
      </p>
<pre class="programlisting"><span class="comment">// Meets the requirements of SyncReadStream</span>
<span class="keyword">struct</span> <span class="identifier">sync_read_stream</span>
<span class="special">{</span>
    <span class="comment">// Returns the number of bytes read upon success, otherwise throws an exception</span>
    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">MutableBufferSequence</span><span class="special">&gt;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">read_some</span><span class="special">(</span><span class="identifier">MutableBufferSequence</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">buffers</span><span class="special">);</span>

    <span class="comment">// Returns the number of bytes read successfully, sets the error code if a failure occurs</span>
    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">MutableBufferSequence</span><span class="special">&gt;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">read_some</span><span class="special">(</span><span class="identifier">MutableBufferSequence</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">buffers</span><span class="special">,</span> <span class="identifier">error_code</span><span class="special">&amp;</span> <span class="identifier">ec</span><span class="special">);</span>
<span class="special">};</span>

<span class="comment">// Meets the requirements of SyncWriteStream</span>
<span class="keyword">struct</span> <span class="identifier">sync_write_stream</span>
<span class="special">{</span>
    <span class="comment">// Returns the number of bytes written upon success, otherwise throws an exception</span>
    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ConstBufferSequence</span><span class="special">&gt;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">write_some</span><span class="special">(</span><span class="identifier">ConstBufferSequence</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">buffers</span><span class="special">);</span>

    <span class="comment">// Returns the number of bytes written successfully, sets the error code if a failure occurs</span>
    <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">ConstBufferSequence</span><span class="special">&gt;</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">write_some</span><span class="special">(</span><span class="identifier">ConstBufferSequence</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">buffers</span><span class="special">,</span> <span class="identifier">error_code</span><span class="special">&amp;</span> <span class="identifier">ec</span><span class="special">);</span>
<span class="special">};</span>
</pre>
<p>
        A <span class="emphasis"><em>synchronous stream algorithm</em></span> is written as a function
        template accepting a stream object meeting the named requirements for synchronous
        reading, writing, or both. This example shows an algorithm which writes text
        and uses exceptions to indicate errors:
      </p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">SyncWriteStream</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">hello</span> <span class="special">(</span><span class="identifier">SyncWriteStream</span><span class="special">&amp;</span> <span class="identifier">stream</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span> <span class="identifier">cb</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">);</span>
    <span class="keyword">do</span>
    <span class="special">{</span>
        <span class="keyword">auto</span> <span class="identifier">bytes_transferred</span> <span class="special">=</span> <span class="identifier">stream</span><span class="special">.</span><span class="identifier">write_some</span><span class="special">(</span><span class="identifier">cb</span><span class="special">);</span> <span class="comment">// may throw</span>
        <span class="identifier">cb</span> <span class="special">+=</span> <span class="identifier">bytes_transferred</span><span class="special">;</span> <span class="comment">// adjust the pointer and size</span>
    <span class="special">}</span>
    <span class="keyword">while</span> <span class="special">(</span><span class="identifier">cb</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&gt;</span> <span class="number">0</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
        The same algorithm may be expressed using error codes instead of exceptions:
      </p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">SyncWriteStream</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">hello</span> <span class="special">(</span><span class="identifier">SyncWriteStream</span><span class="special">&amp;</span> <span class="identifier">stream</span><span class="special">,</span> <span class="identifier">error_code</span><span class="special">&amp;</span> <span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span> <span class="identifier">cb</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">);</span>
    <span class="keyword">do</span>
    <span class="special">{</span>
        <span class="keyword">auto</span> <span class="identifier">bytes_transferred</span> <span class="special">=</span> <span class="identifier">stream</span><span class="special">.</span><span class="identifier">write_some</span><span class="special">(</span><span class="identifier">cb</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">);</span>
        <span class="identifier">cb</span> <span class="special">+=</span> <span class="identifier">bytes_transferred</span><span class="special">;</span> <span class="comment">// adjust the pointer and size</span>
    <span class="special">}</span>
    <span class="keyword">while</span> <span class="special">(</span><span class="identifier">cb</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">&gt;</span> <span class="number">0</span> <span class="special">&amp;&amp;</span> <span class="special">!</span> <span class="identifier">ec</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<h5>
<a name="beast.using_io.asio_refresher.h2"></a>
        <span class="phrase"><a name="beast.using_io.asio_refresher.asynchronous_i_o"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.asynchronous_i_o">Asynchronous
        I/O</a>
      </h5>
<p>
        An asynchronous operation begins with a call to an <a href="../../../../../../doc/html/boost_asio/reference/asynchronous_operations.html" target="_top"><span class="emphasis"><em>initiating
        function</em></span></a>, which starts the operation and returns to the
        caller immediately. This <span class="emphasis"><em>outstanding</em></span> asynchronous operation
        proceeds concurrently without blocking the caller. When the externally observable
        side effects are fully established, a movable function object known as a
        <a href="../../../../../../doc/html/boost_asio/reference/CompletionHandler.html" target="_top"><span class="emphasis"><em>completion
        handler</em></span></a> provided in the initiating function call is queued
        for execution with the results, which may include the error code and other
        specific information. An asynchronous operation is said to be <span class="emphasis"><em>completed</em></span>
        after the completion handler is queued. The code that follows shows how some
        text may be written to a socket asynchronously, invoking a lambda when the
        operation is complete:
      </p>
<pre class="programlisting"><span class="comment">// initiate an asynchronous write operation</span>
<span class="identifier">net</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">),</span>
    <span class="special">[](</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bytes_transferred</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="comment">// this lambda is invoked when the write operation completes</span>
        <span class="keyword">if</span><span class="special">(!</span> <span class="identifier">ec</span><span class="special">)</span>
            <span class="identifier">assert</span><span class="special">(</span><span class="identifier">bytes_transferred</span> <span class="special">==</span> <span class="number">13</span><span class="special">);</span>
        <span class="keyword">else</span>
            <span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"Error: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">ec</span><span class="special">.</span><span class="identifier">message</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
    <span class="special">});</span>
<span class="comment">// meanwhile, the operation is outstanding and execution continues from here</span>
</pre>
<p>
        Every completion handler (also referred to as a <a href="https://en.wikipedia.org/wiki/Continuation" target="_top"><span class="emphasis"><em>continuation</em></span></a>)
        has both an <a href="../../../../../../doc/html/boost_asio/overview/core/allocation.html" target="_top"><span class="emphasis"><em>associated
        allocator</em></span></a> returned by <a href="../../../../../../doc/html/boost_asio/reference/get_associated_allocator.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">get_associated_allocator</span></code></a>,
        and an <a href="../../../../../../doc/html/boost_asio/reference/associated_executor.html" target="_top"><span class="emphasis"><em>associated
        executor</em></span></a> returned by <a href="../../../../../../doc/html/boost_asio/reference/get_associated_executor.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">get_associated_executor</span></code></a>.
        These associations may be specified intrusively:
      </p>
<pre class="programlisting"><span class="comment">// The following is a completion handler expressed</span>
<span class="comment">// as a function object, with a nested associated</span>
<span class="comment">// allocator and a nested associated executor.</span>
<span class="keyword">struct</span> <span class="identifier">handler</span>
<span class="special">{</span>
    <span class="keyword">using</span> <span class="identifier">allocator_type</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;;</span>
    <span class="identifier">allocator_type</span> <span class="identifier">get_allocator</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">using</span> <span class="identifier">executor_type</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">;</span>
    <span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>

    <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">beast</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">);</span>
<span class="special">};</span>
</pre>
<p>
        Or these associations may be specified non-intrusively, by specializing the
        class templates <a href="../../../../../../doc/html/boost_asio/reference/associated_allocator.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">associated_allocator</span></code></a>
        and <a href="../../../../../../doc/html/boost_asio/reference/associated_executor.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">associated_executor</span></code></a>:
      </p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">asio</span> <span class="special">{</span>

<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">associated_allocator</span><span class="special">&lt;</span><span class="identifier">handler</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;</span>
<span class="special">{</span>
    <span class="keyword">using</span> <span class="identifier">type</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;;</span>

    <span class="keyword">static</span>
    <span class="identifier">type</span>
    <span class="identifier">get</span><span class="special">(</span><span class="identifier">handler</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">h</span><span class="special">,</span>
        <span class="identifier">Allocator</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">alloc</span> <span class="special">=</span> <span class="identifier">Allocator</span><span class="special">{})</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="special">};</span>

<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">associated_executor</span><span class="special">&lt;</span><span class="identifier">handler</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
<span class="special">{</span>
    <span class="keyword">using</span> <span class="identifier">type</span> <span class="special">=</span> <span class="identifier">any_io_executor</span><span class="special">;</span>

    <span class="keyword">static</span>
    <span class="identifier">type</span>
    <span class="identifier">get</span><span class="special">(</span><span class="identifier">handler</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">h</span><span class="special">,</span>
        <span class="identifier">Executor</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">ex</span> <span class="special">=</span> <span class="identifier">Executor</span><span class="special">{})</span> <span class="keyword">noexcept</span><span class="special">;</span>
<span class="special">};</span>

<span class="special">}</span> <span class="comment">// boost</span>
<span class="special">}</span> <span class="comment">// asio</span>
</pre>
<p>
        The function <a href="../../../../../../doc/html/boost_asio/reference/bind_executor.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">bind_executor</span></code></a>
        may be used when the caller wants to change the executor of a completion
        handler.
      </p>
<p>
        The allocator is used by the implementation to obtain any temporary storage
        necessary to perform the operation. Temporary allocations are always freed
        before the completion handler is invoked. The executor is a cheaply copyable
        object providing the algorithm used to invoke the completion handler. Unless
        customized by the caller, a completion handler defaults to using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>
        and the executor of the corresponding I/O object.
      </p>
<p>
        Networking prescribes facilities to determine the context in which handlers
        run. Every I/O object refers to an <a href="../../../../../../doc/html/boost_asio/reference/ExecutionContext.html" target="_top"><span class="emphasis"><em>ExecutionContext</em></span></a>
        for obtaining the <a href="../../../../../../doc/html/boost_asio/reference/Executor1.html" target="_top"><span class="emphasis"><em>Executor</em></span></a>
        instance used to invoke completion handlers. An executor determines where
        and how completion handlers are invoked. Executors obtained from an instance
        of <a href="../../../../../../doc/html/boost_asio/reference/io_context.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">io_context</span></code></a>
        offer a basic guarantee: handlers will only be invoked from threads which
        are currently calling <a href="../../../../../../doc/html/boost_asio/reference/io_context/run/overload1.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span></code></a>.
      </p>
<p>
        The <a href="../../../../../../doc/html/boost_asio/reference/AsyncReadStream.html" target="_top"><span class="emphasis"><em>AsyncReadStream</em></span></a>
        and <a href="../../../../../../doc/html/boost_asio/reference/AsyncWriteStream.html" target="_top"><span class="emphasis"><em>AsyncWriteStream</em></span></a>
        concepts define requirements for <span class="emphasis"><em>asynchronous streams</em></span>:
        a portable I/O abstraction that exchanges data asynchronously using buffer
        sequences to represent bytes and <code class="computeroutput"><span class="identifier">error_code</span></code>
        to report any failures. An <span class="emphasis"><em>asynchronous stream algorithm</em></span>
        is written as a templated initiating function template accepting a stream
        object meeting the named requirements for asynchronous reading, writing,
        or both. This example shows an algorithm which writes some text to an asynchronous
        stream:
      </p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">AsyncWriteStream</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">WriteHandler</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">async_hello</span> <span class="special">(</span><span class="identifier">AsyncWriteStream</span><span class="special">&amp;</span> <span class="identifier">stream</span><span class="special">,</span> <span class="identifier">WriteHandler</span><span class="special">&amp;&amp;</span> <span class="identifier">handler</span><span class="special">)</span>
<span class="special">{</span>
    <span class="identifier">net</span><span class="special">::</span><span class="identifier">async_write</span> <span class="special">(</span><span class="identifier">stream</span><span class="special">,</span>
        <span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">),</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">WriteHandler</span><span class="special">&gt;(</span><span class="identifier">handler</span><span class="special">));</span>
<span class="special">}</span>
</pre>
<h5>
<a name="beast.using_io.asio_refresher.h3"></a>
        <span class="phrase"><a name="beast.using_io.asio_refresher.concurrency"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.concurrency">Concurrency</a>
      </h5>
<p>
        I/O objects such as sockets and streams <span class="bold"><strong>are not thread-safe</strong></span>.
        Although it is possible to have more than one operation outstanding (for
        example, a simultaneous asynchronous read and asynchronous write) the stream
        object itself may only be accessed from one thread at a time. This means
        that member functions such as move constructors, destructors, or initiating
        functions must not be called concurrently. Usually this is accomplished with
        synchronization primitives such as a <a href="https://en.cppreference.com/w/cpp/thread/mutex" target="_top"><code class="computeroutput"><span class="identifier">mutex</span></code></a>, but concurrent network programs
        need a better way to access shared resources, since acquiring ownership of
        a mutex could block threads from performing uncontended work. For efficiency,
        networking adopts a model of using threads without explicit locking by requiring
        all access to I/O objects to be performed within a <a href="../../../../../../doc/html/boost_asio/overview/core/strands.html" target="_top"><span class="emphasis"><em>strand</em></span></a>.
      </p>
<h5>
<a name="beast.using_io.asio_refresher.h4"></a>
        <span class="phrase"><a name="beast.using_io.asio_refresher.universal_model"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.universal_model">Universal
        Model</a>
      </h5>
<p>
        Because completion handlers cause an inversion of the flow of control, sometimes
        other methods of attaching a continuation are desired. Networking provides
        the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf" target="_top"><span class="emphasis"><em>Universal
        Model for Asynchronous Operations</em></span></a>, providing a customizable
        means for transforming the signature of the initiating function to use other
        types of objects and methods in place of a completion handler callback. For
        example to call to write a string to a socket asynchronously, using a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span></code>
        to receive the number of bytes transferred thusly looks like this:
      </p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span>
    <span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">),</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">use_future</span><span class="special">);</span>
</pre>
<p>
        This functionality is enabled by passing the variable <a href="../../../../../../doc/html/boost_asio/reference/use_future.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">use_future</span></code></a>
        (of type <a href="../../../../../../doc/html/boost_asio/reference/use_future_t.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">use_future_t</span><span class="special">&lt;&gt;</span></code></a>) in place of the completion
        handler. The same <code class="computeroutput"><span class="identifier">async_write</span></code>
        function overload can work with a <a href="https://en.wikipedia.org/wiki/Fiber_(computer_science)" target="_top"><span class="emphasis"><em>fiber</em></span></a>
        launched with <a href="../../../../../../doc/html/boost_asio/reference/spawn/overload1.html" target="_top"><code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">spawn</span></code></a>:
      </p>
<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">spawn</span><span class="special">(</span>
    <span class="special">[&amp;</span><span class="identifier">sock</span><span class="special">](</span><span class="identifier">net</span><span class="special">::</span><span class="identifier">yield_context</span> <span class="identifier">yield</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bytes_transferred</span> <span class="special">=</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span>
            <span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">),</span> <span class="identifier">yield</span><span class="special">);</span>
        <span class="special">(</span><span class="keyword">void</span><span class="special">)</span><span class="identifier">bytes_transferred</span><span class="special">;</span>
    <span class="special">});</span>
</pre>
<p>
        In both of these cases, an object with a specific type is used in place of
        the completion handler, and the return value of the initiating function is
        transformed from <code class="computeroutput"><span class="keyword">void</span></code> to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">&gt;</span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span></code>.
        The handler is sometimes called a <a href="../../../../../../doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.completion_tokens_and_handlers" target="_top"><span class="emphasis"><em>CompletionToken</em></span></a>
        when used in this context. The return type transformation is supported by
        customization points in the initiating function signature. Here is the signature
        for <a href="../../../../../../doc/html/boost_asio/reference/async_write/overload1.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">async_write</span></code></a>:
      </p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span>
    <span class="keyword">class</span> <span class="identifier">AsyncWriteStream</span><span class="special">,</span>
    <span class="keyword">class</span> <span class="identifier">ConstBufferSequence</span><span class="special">,</span>
    <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">&gt;</span>
<span class="keyword">auto</span>
<span class="identifier">async_write</span><span class="special">(</span>
    <span class="identifier">AsyncWriteStream</span><span class="special">*</span> <span class="identifier">stream</span><span class="special">,</span>                       <span class="comment">// references are passed as pointers</span>
    <span class="identifier">ConstBufferSequence</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">buffers</span><span class="special">,</span>
    <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span>                        <span class="comment">// a handler, or a special object.</span>
    <span class="special">-&gt;</span>
    <span class="keyword">typename</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">async_result</span><span class="special">&lt;</span>                     <span class="comment">// return-type customization point.</span>
        <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">,</span> <span class="comment">// type used to specialize async_result.</span>
        <span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">)</span>               <span class="comment">// underlying completion handler signature.</span>
            <span class="special">&gt;::</span><span class="identifier">return_type</span><span class="special">;</span>
</pre>
<p>
        The type of the function's return value is determined by the <a href="../../../../../../doc/html/boost_asio/reference/async_result.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">async_result</span></code></a>
        customization point, which comes with specializations for common library
        types such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span></code> and may also be specialized for
        user-defined types. The body of the initiating function calls the <a href="../../../../../../doc/html/boost_asio/reference/async_inititate.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">async_initiate</span></code></a>
        helper to capture the arguments and forward them to the specialization of
        <code class="computeroutput"><span class="identifier">async_result</span></code>. An additional
        "initiation function" object is provided which <code class="computeroutput"><span class="identifier">async_result</span></code>
        may use to immediately launch the operation, or defer the launch of the operation
        until some point in the future (this is called "lazy execution").
        The initiation function object receives the internal completion handler which
        matches the signature expected by the initiating function:
      </p>
<pre class="programlisting"><span class="keyword">return</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">async_initiate</span><span class="special">&lt;</span>
    <span class="identifier">CompletionToken</span><span class="special">,</span>
    <span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">)&gt;(</span>
        <span class="identifier">run_async_write</span><span class="special">{},</span>              <span class="comment">// The "initiation" object.</span>
        <span class="identifier">token</span><span class="special">,</span>                          <span class="comment">// Token must come before other arguments.</span>
        <span class="special">&amp;</span><span class="identifier">stream</span><span class="special">,</span>                        <span class="comment">// Additional captured arguments are</span>
        <span class="identifier">buffers</span><span class="special">);</span>                       <span class="comment">//   forwarded to the initiation object.</span>
</pre>
<p>
        This transformed, internal handler is responsible for the finalizing step
        that delivers the result of the operation to the caller. For example, when
        using <code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">use_future</span></code> the internal handler will deliver
        the result by calling <a href="https://en.cppreference.com/w/cpp/thread/promise/set_value" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">promise</span><span class="special">::</span><span class="identifier">set_value</span></code></a>
        on the promise object returned by the initiating function.
      </p>
<h5>
<a name="beast.using_io.asio_refresher.h5"></a>
        <span class="phrase"><a name="beast.using_io.asio_refresher.using_networking"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.using_networking">Using
        Networking</a>
      </h5>
<p>
        Most library stream algorithms require a <a href="../../../../../../doc/html/boost_asio/reference/ip__tcp/socket.html" target="_top"><code class="computeroutput"><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span></code></a>,
        <a href="../../../../../../doc/html/boost_asio/reference/ssl__stream.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span></code></a>,
        or other <a class="link" href="../concepts/streams.html" title="Streams"><span class="emphasis"><em>Stream</em></span></a>
        object that has already established communication with a remote peer. This
        example is provided as a reminder of how to work with sockets:
      </p>
<pre class="programlisting"><span class="comment">// The resolver is used to look up IP addresses and port numbers from a domain and service name pair</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span> <span class="identifier">r</span><span class="special">{</span><span class="identifier">ioc</span><span class="special">};</span>

<span class="comment">// A socket represents the local end of a connection between two peers</span>
<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">stream</span><span class="special">{</span><span class="identifier">ioc</span><span class="special">};</span>

<span class="comment">// Establish a connection before sending and receiving data</span>
<span class="identifier">net</span><span class="special">::</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">stream</span><span class="special">,</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">resolve</span><span class="special">(</span><span class="string">"www.example.com"</span><span class="special">,</span> <span class="string">"http"</span><span class="special">));</span>

<span class="comment">// At this point `stream` is a connected to a remote</span>
<span class="comment">// host and may be used to perform stream operations.</span>
</pre>
<p>
        Throughout this documentation identifiers with the following names have special
        meaning:
      </p>
<div class="table">
<a name="beast.using_io.asio_refresher.global_variables"></a><p class="title"><b>Table 1.3. Global Variables</b></p>
<div class="table-contents"><table class="table" summary="Global Variables">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
                <p>
                  Name
                </p>
              </th>
<th>
                <p>
                  Description
                </p>
              </th>
</tr></thead>
<tbody>
<tr>
<td>
                <p>
                  <a href="../../../../../../doc/html/boost_asio/reference/io_context.html" target="_top"><span class="bold"><strong><code class="computeroutput"><span class="identifier">ioc</span></code></strong></span></a>
                </p>
              </td>
<td>
                <p>
                  A variable of type <a href="../../../../../../doc/html/boost_asio/reference/io_context.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">io_context</span></code></a> which is running
                  on one separate thread, and upon which an <a href="../../../../../../doc/html/boost_asio/reference/executor_work_guard.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">executor_work_guard</span></code></a> object
                  has been constructed.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <a href="../../../../../../doc/html/boost_asio/reference/ip__tcp/socket.html" target="_top"><span class="bold"><strong><code class="computeroutput"><span class="identifier">sock</span></code></strong></span></a>
                </p>
              </td>
<td>
                <p>
                  A variable of type <a href="../../../../../../doc/html/boost_asio/reference/ip__tcp/socket.html" target="_top"><code class="computeroutput"><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span></code></a> which has already
                  been connected to a remote host.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <a href="../../../../../../doc/html/boost_asio/reference/ssl__stream.html" target="_top"><span class="bold"><strong><code class="computeroutput"><span class="identifier">ssl_sock</span></code></strong></span></a>
                </p>
              </td>
<td>
                <p>
                  A variable of type <a href="../../../../../../doc/html/boost_asio/reference/ssl__stream.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span><span class="special">&lt;</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&gt;</span></code></a>
                  which is already connected and has handshaked with a remote host.
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  <a class="link" href="../ref/boost__beast__websocket__stream.html" title="websocket::stream"><span class="bold"><strong><code class="computeroutput"><span class="identifier">ws</span></code></strong></span></a>
                </p>
              </td>
<td>
                <p>
                  A variable of type <a class="link" href="../ref/boost__beast__websocket__stream.html" title="websocket::stream"><code class="computeroutput"><span class="identifier">websocket</span><span class="special">::</span><span class="identifier">stream</span><span class="special">&lt;</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&gt;</span></code></a>
                  which is already connected with a remote host.
                </p>
              </td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break">
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2016-2019 Vinnie
      Falco<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../using_io.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_io.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stream_types.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
